home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 26
/
Cream of the Crop 26.iso
/
program
/
vol16n13.zip
/
OPENTR.ZIP
/
OT_SRC.ZIP
/
MAINFRM.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-05-26
|
28KB
|
845 lines
// MainFrm.cpp : implementation of the CMainFrame class
//
// OpenTrap Version 1.00 by Gregory A. Wolking
// Copyright ⌐ 1997 Ziff-Davis Publishing
// First published in PC Magazine, US Edition, July 1997.
#include "stdafx.h"
#include <afxpriv.h> // Required for definition of WM_KICKIDLE
#include "OpenTrap.h"
#include "MainFrm.h"
#include "OTDoc.h"
#include "OTView.h"
#include "OTextern.h"
#include "OptDlg.h"
#include "FiltDlg.h"
#include "PageDlg.h"
#include "ExpDlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
#define WM_MY_STOP_LOG (WM_USER + 1) // Sent by VXD to signal log full.
#define WM_MY_TASKBAR_NOTIFY (WM_USER + 2) // Used for Taskbar Notification messages.
// Text for taskbar icon tooltip.
const char szTip_Text[] = "OpenTrap is logging -- double-click to activate";
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_COMMAND(ID_LOGGING_START, OnLoggingStart)
ON_COMMAND(ID_LOGGING_STOP, OnLoggingStop)
ON_COMMAND(ID_LOGGING_OPTIONS, OnLoggingOptions)
ON_UPDATE_COMMAND_UI(ID_FILE_SAVE, OnUpdateFileSave)
ON_UPDATE_COMMAND_UI(ID_FILE_SAVE_AS, OnUpdateFileSaveAs)
ON_COMMAND(ID_FILE_EXPORT, OnFileExport)
ON_COMMAND(ID_VIEW_FILTER, OnViewFilter)
ON_COMMAND(ID_VIEW_RECNUM, OnViewRecnum)
ON_UPDATE_COMMAND_UI(ID_VIEW_RECNUM, OnUpdateViewRecnum)
ON_WM_CLOSE()
ON_UPDATE_COMMAND_UI(ID_FILE_PRINT, OnUpdateFilePrint)
ON_COMMAND(ID_VIEW_FONT, OnViewFont)
ON_COMMAND(ID_VIEW_FONT_DEFAULT, OnViewFontDefault)
ON_UPDATE_COMMAND_UI(ID_VIEW_FONT_DEFAULT, OnUpdateViewFontDefault)
ON_UPDATE_COMMAND_UI(ID_FILE_NEW, OnUpdateLogging)
ON_UPDATE_COMMAND_UI(ID_FILE_OPEN, OnUpdateLogging)
ON_UPDATE_COMMAND_UI(ID_FILE_EXPORT, OnUpdateFileSaveAs)
ON_UPDATE_COMMAND_UI(ID_VIEW_FILTER, OnUpdateLogging)
ON_UPDATE_COMMAND_UI(ID_FILE_PRINT_SETUP, OnUpdateLogging)
ON_WM_QUERYENDSESSION()
//}}AFX_MSG_MAP
// Global help commands
ON_COMMAND(ID_HELP_FINDER, CFrameWnd::OnHelpFinder)
ON_COMMAND(ID_HELP, CFrameWnd::OnHelp)
ON_COMMAND(ID_CONTEXT_HELP, CFrameWnd::OnContextHelp)
ON_COMMAND(ID_DEFAULT_HELP, CFrameWnd::OnHelpFinder)
ON_COMMAND_RANGE(ID_VIEW_TOP, ID_VIEW_GOTO, OnViewMove)
ON_COMMAND_EX(ID_VIEW_VIEWTOOLS, CFrameWnd::OnBarCheck)
ON_UPDATE_COMMAND_UI(ID_VIEW_VIEWTOOLS, CFrameWnd::OnUpdateControlBarMenu)
ON_UPDATE_COMMAND_UI_RANGE(ID_VIEW_TOP, ID_VIEW_GOTO, OnUpdateViewMove)
ON_UPDATE_COMMAND_UI_RANGE(ID_INDICATOR_IDLE, ID_INDICATOR_FILTER, OnUpdateIndicators)
ON_UPDATE_COMMAND_UI_RANGE(ID_LOGGING_START, ID_LOGGING_OPTIONS, OnUpdateLogging)
// User-defined messages
ON_MESSAGE(WM_MY_STOP_LOG, On_VXD_Stop_Request)
ON_MESSAGE(WM_MY_TASKBAR_NOTIFY, On_Taskbar_Notify)
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_IDLE,
ID_INDICATOR_FILTER,
ID_INDICATOR_POS
};
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
WINDOWPLACEMENT wp;
if (ReadWindowPlacement(&wp))
SetWindowPlacement(&wp);
if (!m_wndToolBar.Create(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
// When creating our Navigation toolbar, be sure to assign it the same ID
// as its menu command so we can hook it into the existing
// MFC toolbar/menu mechanism.
if (!m_wndViewToolBar.Create(this,
WS_CHILD | WS_VISIBLE | CBRS_TOP | CBRS_SIZE_DYNAMIC | CBRS_TOOLTIPS | CBRS_FLYBY, ID_VIEW_VIEWTOOLS) ||
!m_wndViewToolBar.LoadToolBar(IDR_VIEWTOOLS))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// Make the toolbars dockable
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndViewToolBar.SetBarStyle(m_wndViewToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndToolBar.SetWindowText("File Tools");
m_wndViewToolBar.EnableDocking(CBRS_ALIGN_ANY);
m_wndViewToolBar.SetWindowText("Navigation Tools");
// Let toolbars dock anywhere
EnableDocking(CBRS_ALIGN_ANY);
// Attach the toolbars to the main window.
DockControlBar(&m_wndToolBar, AFX_IDW_DOCKBAR_TOP);
DockControlBarLeftOf(&m_wndViewToolBar, &m_wndToolBar);
// Read tool/status bar settings from the Registry.
LoadBarState("1.0\\Settings");
m_bInTaskBar = FALSE;
m_bVisible = TRUE;
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
return CFrameWnd::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CMainFrame message handlers
// Windows messages.
// Called when user closes the main window.
void CMainFrame::OnClose()
{
if (g_bIsLogging) // If we're logging,
{
if (m_bInTaskBar) // And the "hide to taskbar" option is enabled,
{
ShowWindow(SW_HIDE); // just hide the main window.
m_bVisible = FALSE;
return;
}
// Otherwise, stop logging before the window closes.
if (AfxMessageBox(IDP_QUERY_LOG_STOP, MB_ICONQUESTION | MB_YESNO) == IDYES)
OnLoggingStop();
else
return;
}
// Kludge for saving Window position if minimized.
if (IsIconic()) // If minimized,
ShowWindow(SW_RESTORE); // Restore to normal position.
WINDOWPLACEMENT wp; // Save window position.
wp.length = sizeof wp;
if (GetWindowPlacement(&wp))
{
wp.flags = 0;
if (IsZoomed())
wp.flags |= WPF_RESTORETOMAXIMIZED;
WriteWindowPlacement(&wp);
}
Do_Taskbar_Icon(NIM_DELETE); // Kill taskbar icon.
CFrameWnd::OnClose(); // Call base class to close the window.
}
// Called immediately before the main window is destroyed.
// The window has already been removed from the screen, but it still exists.
void CMainFrame::OnDestroy()
{
SaveBarState("1.0\\Settings");
if (g_bIsLogging)
Stop_Logging();
if (g_pBufferStart != NULL)
{
delete [] g_pBufferStart;
g_pBufferStart = NULL;
}
CFrameWnd::OnDestroy();
}
// Called when Windows itself is shutting down.
// This hook is necessary to ensure that logging stops and user is prompted
// (if appropriate) to save the log before Windows exits.
BOOL CMainFrame::OnQueryEndSession()
{
if (g_bIsLogging) // If we're logging,
OnLoggingStop(); // stop.
// Call base class to save modified log if needed.
if (!CFrameWnd::OnQueryEndSession())
return FALSE;
return TRUE;
}
////////////////////////////////////
// ToolBar and Menu command handlers
// Start Logging
void CMainFrame::OnLoggingStart()
{
COpenTrapDoc *pDoc = (COpenTrapDoc *) GetActiveDocument();
if (!g_bIsLogging)
{
m_intStartRecCount = g_intRecCount; // Save current record count.
if (Start_Logging()) // Try to start logging.
{
CString txt("OpenTrap [Logging to "); // Set window caption if successful.
txt += pDoc->GetTitle();
txt += "]";
SetWindowText(txt);
if (g_bHide)
{
Do_Taskbar_Icon(NIM_ADD);
m_bInTaskBar = TRUE;
ShowWindow(SW_HIDE);
m_bVisible = FALSE;
}
}
else
AfxMessageBox(IDP_LOG_START_FAIL, MB_OK, 0); // Error message if not;
}
pDoc->UpdateAllViews(NULL, 0, 0); // Update the display.
}
// Stop Logging
void CMainFrame::OnLoggingStop()
{
COpenTrapDoc *pDoc = (COpenTrapDoc *) GetActiveDocument();
if (g_bIsLogging)
{
CString txt("OpenTrap - "); // Reset Window caption.
txt += pDoc->GetTitle();
Stop_Logging(); // Turn off the thread.
SetWindowText(txt); // Reset Window caption.
if (m_bInTaskBar)
{
Do_Taskbar_Icon(NIM_DELETE);
if (!IsWindowVisible())
ShowWindow(SW_SHOW);
m_bInTaskBar = FALSE;
m_bVisible = TRUE;
}
}
if (g_intRecCount != m_intStartRecCount) // If any records were captured,
{
pDoc->SetModifiedFlag(); // Mark the document as dirty.
pDoc->Fix_Pointers(g_intRecCount); // Rebuild list pointers.
}
pDoc->UpdateAllViews(NULL, 0, 0); // Update the display.
}
// Presents the Logging Options dialog.
void CMainFrame::OnLoggingOptions()
{
COptDlg dlg;
// Set dialog controls to match current settings.
dlg.m_bHide = g_bHide;
dlg.m_bErrorsOnly = g_bLogErrorsOnly;
dlg.m_intAction = (g_bLogOpensOnly) ? 1 : 0;
dlg.m_intLogSize = g_intLogSizeK;
if (g_dwWatchVM == LOG_ALL)
dlg.m_intVM = 0;
else
dlg.m_intVM = ((g_dwWatchVM == LOG_WINDOWS_ONLY) ? 1 : 2);
if (dlg.DoModal() == IDOK) // Launch the dialog. If user says OK,
{
g_bHide = dlg.m_bHide;
g_bLogErrorsOnly = dlg.m_bErrorsOnly; // Set options from the
g_bLogOpensOnly = dlg.m_intAction == 1; // dialog.
switch (dlg.m_intVM)
{
case 0:
g_dwWatchVM = LOG_ALL;
break;
case 1:
g_dwWatchVM = LOG_WINDOWS_ONLY;
break;
case 2:
g_dwWatchVM = LOG_ALL_DOS;
}
if (dlg.m_intLogSize != g_intLogSizeK) // Did user change the buffer size?
{
void * new_buf; // Try to reallocate it if so.
new_buf = realloc(g_pBufferStart, (dlg.m_intLogSize * 1024));
if (new_buf)
{
g_intLogSizeK = dlg.m_intLogSize; // If successful, save new log size.
g_pBufferStart = (char *) new_buf; // Update buffer start pointer.
// realloc() may have moved the buffer
if (g_intRecCount) // so if it's not empty, fix the pointer chain.
((COpenTrapDoc *) GetActiveDocument())->Fix_Pointers(g_intRecCount);
else
g_pNextRec = g_pBufferStart; // Otherwise just end equal to start.
// Calculate "safe" end of buffer for VXD, leaving enough room for
// the largest possible event record.
g_pBufSafeEnd = (g_pBufferStart + (g_intLogSizeK * 1024) - (sizeof(packed_record) + MAX_PATH + 2));
// Set full flag if not enough room for another record.
g_bLogFull = g_pNextRec > g_pBufSafeEnd;
}
else
MessageBox("Reallocation failed\nBuffer remains unchanged", "OpenTrap", MB_OK);
}
// Save settings if requested.
if (dlg.m_bSaveSettings)
{
CWinApp* myApp = AfxGetApp();
myApp->WriteProfileInt(g_szLogKey, "BufferSizeK", g_intLogSizeK);
myApp->WriteProfileInt(g_szLogKey, "LogErrorsOnly", g_bLogErrorsOnly);
myApp->WriteProfileInt(g_szLogKey, "LogActions", g_bLogOpensOnly);
myApp->WriteProfileInt(g_szLogKey, "WatchVMs", g_dwWatchVM);
myApp->WriteProfileInt(g_szLogKey, "UseTaskBar", g_bHide);
}
}
}
// Presents the Export Options dialog and, if requested,
// writes a text file in the desired format.
void CMainFrame::OnFileExport()
{
COpenTrapDoc * pDoc = (COpenTrapDoc *) GetActiveDocument();
CString t;
int p;
CExpDlg dlg; // Create the dialog.
dlg.m_bUseFilters = g_bWriteFiltered; // Initialize member variables.
dlg.m_bRecNums = g_bExportRecNums;
dlg.m_intFormat = g_bCommaDelimited ? 1 : 0;
if (dlg.DoModal() != IDOK) // Launch the dialog.
return; // Done if user didn't say OK.
g_bWriteFiltered = dlg.m_bUseFilters; // Retrieve settings from dialog.
g_bCommaDelimited = dlg.m_intFormat == 1;
g_bExportRecNums = dlg.m_bRecNums;
t = pDoc->GetTitle(); // Get document name.
while ((p = t.ReverseFind('.')) != -1) // Strip off extension.
t = t.Left(p);
CFileDialog cf(FALSE, // Create a Save As dialog.
".txt", // Default extension if none specified.
(LPCTSTR) t, // Default base filename.
OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT, // No read-only, prompt before overwrite.
"Text log files (*.txt)|*.txt|All Files (*.*)|*.*||", // File filters.
this);
if (cf.DoModal() == IDOK) // Launch dialog. If user said OK,
pDoc->Write_Text_Log(cf.GetPathName()); // write text log to the specified file.
}
// Presents the Filter Options dialog.
void CMainFrame::OnViewFilter()
{
COpenTrapDoc * pDoc = (COpenTrapDoc *) GetActiveDocument();
CFilterDlg dlg; // Create the dialog
dlg.m_bSaveSettings = FALSE; // Initialize member variables.
dlg.m_bBaseName = g_bFilterFileName;
dlg.m_strBaseName = g_strFilterFileName;
dlg.m_bExt = g_bFilterFileExt;
dlg.m_strExt = g_strFilterFileExt;
dlg.m_bModuleName = g_bFilterModule;
dlg.m_strModuleName = g_strFilterModuleName;
dlg.m_intShow = g_intFilterEvents;
dlg.m_bErrorsOnly = g_bFilterErrorsOnly;
if (dlg.DoModal() == IDOK) // Launch the dialog. If user said OK,
{
g_bFilterFileName = dlg.m_bBaseName; // Transfer settings from dialog to global.
g_strFilterFileName = dlg.m_strBaseName;
g_bFilterFileExt = dlg.m_bExt;
g_strFilterFileExt = dlg.m_strExt;
g_bFilterModule = dlg.m_bModuleName;
g_strFilterModuleName = dlg.m_strModuleName;
g_intFilterEvents = dlg.m_intShow;
g_bFilterErrorsOnly = dlg.m_bErrorsOnly;
pDoc->SetFilterFlag();
if (dlg.m_bSaveSettings) // If user checked the Save Settings box,
{
CWinApp * myApp = AfxGetApp(); // Write new settings to the Registry.
myApp->WriteProfileInt(g_szViewKey, "UseBase", g_bFilterFileName);
myApp->WriteProfileString(g_szViewKey, "Base", g_strFilterFileName);
myApp->WriteProfileInt(g_szViewKey, "UseExt", g_bFilterFileExt);
myApp->WriteProfileString(g_szViewKey, "Ext", g_strFilterFileExt);
myApp->WriteProfileInt(g_szViewKey, "UseModule", g_bFilterModule);
myApp->WriteProfileString(g_szViewKey, "Module", g_strFilterModuleName);
myApp->WriteProfileInt(g_szViewKey, "Events", g_intFilterEvents);
myApp->WriteProfileInt(g_szViewKey, "Errors", g_bFilterErrorsOnly);
}
if (g_intRecCount) // If log is not empty,
pDoc->UpdateAllViews(NULL, FALSE, NULL); // Redraw the display with the new filters.
}
}
// Turns Record Number display on and off.
void CMainFrame::OnViewRecnum()
{
COpenTrapDoc* pDoc = (COpenTrapDoc*)GetActiveDocument();
g_bShowNums = !g_bShowNums;
if (g_intRecCount)
pDoc->UpdateAllViews(NULL, TRUE, NULL);
}
// Handles navigation commands
void CMainFrame::OnViewMove(UINT nID)
{
COpenTrapView* pView = (COpenTrapView*)GetActiveView();
COpenTrapDoc* pDoc = pView->GetDocument();
int response = IDOK;
switch (nID)
{
case ID_VIEW_TOP:
pView->m_intCurrent_Page = 1;
pView->SetScrollPos(SB_VERT, 0, FALSE);
break;
case ID_VIEW_PREVIOUS:
--pView->m_intCurrent_Page;
break;
case ID_VIEW_NEXT:
++pView->m_intCurrent_Page;
pView->SetScrollPos(SB_VERT, 0, FALSE);
break;
case ID_VIEW_LAST:
pView->m_intCurrent_Page = pView->m_intPage_Count;
pView->SetScrollPos(SB_VERT, 0, FALSE);
break;
case ID_VIEW_GOTO:
CPageDlg dlg;
dlg.m_intEndPage = pView->m_intPage_Count;
dlg.m_intPageNum = pView->m_intCurrent_Page;
if ((response = dlg.DoModal()) == IDOK)
pView->m_intCurrent_Page = dlg.m_intPageNum;
}
if (response == IDOK)
pDoc->UpdateAllViews(NULL, nID, NULL);
}
// Presents font dialog and attaches new font if necessary.
void CMainFrame::OnViewFont()
{
LOGFONT my_font, *pMyFont;
COpenTrapView* pView = (COpenTrapView*)GetActiveView();
COpenTrapDoc* pDoc = (COpenTrapDoc*)GetActiveDocument();
if (pView->m_fontCustom) // Already using custom font?
{
pMyFont = &my_font; // Point to our LOGFONT structure.
pView->m_fontCustom->GetLogFont(pMyFont); // Load it from the custom font.
}
else
pMyFont = NULL; // Otherwise, dialog comes up with no font selected.
CFontDialog dlg(pMyFont, CF_SCREENFONTS | CF_TTONLY, NULL, this);
if (dlg.DoModal() != IDOK)
return; // Nothing to do if user didn't OK the dialog
// Retrieve font data from the dialog.
// NOTE: The MFC documentation says you can use CFontDialog::GetCurrentSelection(), but
// it fails; it only works while the dialog is active, not after DoModal() returns!
memcpy(&my_font, dlg.m_cf.lpLogFont, sizeof(dlg.m_lf));
if (pView->m_fontCustom) // If custom font was in use,
delete pView->m_fontCustom; // delete it.
pView->m_fontCustom = new CFont; // Create new CFont object.
pView->m_fontCustom->CreateFontIndirect(&my_font); // Load it with desired font.
pDoc->UpdateAllViews(NULL); // Update the display.
}
// Reverts to default system font.
void CMainFrame::OnViewFontDefault()
{
COpenTrapView* pView = (COpenTrapView *)GetActiveView();
COpenTrapDoc* pDoc = (COpenTrapDoc*)GetActiveDocument();
if (pView->m_fontCustom)
{
delete pView->m_fontCustom;
pView->m_fontCustom = NULL;
pDoc->UpdateAllViews(NULL);
}
}
/////////////////////////////
// Custom message handlers
// Handles WM_MY_STOP_LOG message posted by callback function when buffer fills.
LONG CMainFrame::On_VXD_Stop_Request(WPARAM wParam, LPARAM lParam)
{
OnLoggingStop();
return 0L;
}
// Handles notification messages from our task bar icon.
// Note: We only have one icon on the taskbar, so we can
// ignore the icon identifier (wParam).
LONG CMainFrame::On_Taskbar_Notify(WPARAM wParam, LPARAM lParam)
{
if (!m_bVisible) // Ignore taskbar if we're already visible.
{
if (lParam == WM_LBUTTONDBLCLK) // Double click?
{
ShowWindow(SW_SHOW); // Restore the window
m_bVisible = TRUE; // Set flag.
PostMessage(WM_KICKIDLE, 0, 0); // Force command UI update.
}
}
return 0L; // Let the system know that we processed the message.
}
///////////////////////
// User interface update handlers
// These handlers are responsible for enabling and disabling various controls
// (menu commands and toolbar buttons) based on the program's current state.
void CMainFrame::OnUpdateViewFontDefault(CCmdUI* pCmdUI)
{
COpenTrapView* pView = (COpenTrapView *)GetActiveView();
pCmdUI->Enable(pView->m_fontCustom != NULL);
}
void CMainFrame::OnUpdateLogging(CCmdUI* pCmdUI)
{
switch (pCmdUI->m_nID)
{
case ID_LOGGING_STOP: pCmdUI->Enable(g_bIsLogging); break;
case ID_LOGGING_OPTIONS:
case ID_FILE_NEW:
case ID_FILE_OPEN:
case ID_FILE_PRINT_SETUP:
case ID_VIEW_FILTER: pCmdUI->Enable(!g_bIsLogging); break;
case ID_LOGGING_START:
pCmdUI->Enable(!g_bIsLogging && !g_bLogFull);
if (g_intRecCount == 0)
pCmdUI->SetText("Start &Logging");
else
pCmdUI->SetText("Resume &Logging");
}
}
void CMainFrame::OnUpdateFileSave(CCmdUI* pCmdUI)
{
pCmdUI->Enable((!g_bIsLogging) && (g_intRecCount > 0) && GetActiveDocument()->IsModified());
}
void CMainFrame::OnUpdateFileSaveAs(CCmdUI* pCmdUI)
{
pCmdUI->Enable((!g_bIsLogging) && (g_intRecCount > 0));
}
void CMainFrame::OnUpdateViewRecnum(CCmdUI* pCmdUI)
{
pCmdUI->SetCheck(g_bShowNums);
pCmdUI->Enable(!g_bIsLogging);
}
void CMainFrame::OnUpdateViewMove(CCmdUI* pCmdUI)
{
if (g_bIsLogging || g_intRecCount == 0)
{
pCmdUI->Enable(FALSE);
return;
}
COpenTrapView* pView = (COpenTrapView*)GetActiveView();
BOOL status = FALSE;
switch (pCmdUI->m_nID)
{
case ID_VIEW_TOP:
case ID_VIEW_PREVIOUS: status = pView->m_intCurrent_Page > 1; break;
case ID_VIEW_LAST:
case ID_VIEW_NEXT: status = pView->m_intCurrent_Page < pView->m_intPage_Count; break;
case ID_VIEW_GOTO: status = pView->m_intPage_Count > 1;
}
pCmdUI->Enable(status);
}
void CMainFrame::OnUpdateFilePrint(CCmdUI* pCmdUI)
{
COpenTrapView* pView = (COpenTrapView*)GetActiveView();
pCmdUI->Enable((!g_bIsLogging) && (g_intRecCount > 0) && (pView->m_intFilt_Rec_Count > 0));
}
// This function sets the text for the Status Bar display.
void CMainFrame::OnUpdateIndicators(CCmdUI* pCmdUI)
{
switch (pCmdUI->m_nID)
{
case ID_INDICATOR_FILTER:
pCmdUI->Enable(g_bUseFilters);
break;
// The "Position" field serves multiple duties depending on the current mode.
// While logging, it indicates the approximate number of records in the buffer.
// While idle, it shows either the current page number or "Log is empty".
case ID_INDICATOR_POS:
{
CString txt;
if (g_bIsLogging)
{
txt.Format("%u records captured", g_intRecCount);
}
else
{
pCmdUI->Enable(TRUE);
if (g_intRecCount == 0)
txt = "Log is empty";
else
{
COpenTrapView * pView = (COpenTrapView*)GetActiveView();
if (pView->m_intFilt_Rec_Count == 0)
txt.Format("%u records on file", g_intRecCount);
else
txt.Format("Page %u of %u", pView->m_intCurrent_Page, pView->m_intPage_Count);
}
}
pCmdUI->SetText(txt);
}
break;
case ID_INDICATOR_IDLE:
if (g_bIsLogging)
pCmdUI->SetText("LOGGING");
else
{
if (g_bLogFull)
pCmdUI->SetText("LOG FULL");
else
pCmdUI->SetText("IDLE");
}
}
}
////////////////////////////
// Helper functions.
// Loads FUNCTRAP.VXD and launches logging thread.
// Returns TRUE if logging started successfully.
// Returns FALSE and displays appropriate error message if:
// 1. Unable to load FUNCTRAP.VXD
// 2. Unable to launch logging thread.
BOOL CMainFrame::Start_Logging(void)
{
// Open the handle to the VXD
g_hVXD = CreateFile( VXD_NAME, 0, 0, NULL, 0, FILE_FLAG_DELETE_ON_CLOSE, NULL );
if ( g_hVXD == INVALID_HANDLE_VALUE )
{
AfxMessageBox(IDP_VXD_LOAD_FAIL, MB_ICONINFORMATION);
return FALSE;
}
// Calculate safe end of buffer to prevent overruns.
g_pBufSafeEnd = g_pBufferStart + ((g_intLogSizeK * 1024) - 400);
// Initialize the VXD.
DeviceIoControl(g_hVXD, VXD_GET_VER, g_pBufferStart, 4, NULL, 0, NULL, NULL );
// Initialize trap condition records.
g_tcCond1.tc_callback = g_tcCond2.tc_callback = (DWORD) &our_callback;
g_tcCond1.tc_misc = g_tcCond2.tc_misc = 0;
g_tcCond1.tc_vm_num = g_tcCond2.tc_vm_num = g_dwWatchVM;
// Create Critical Section and Event objects used to control worker thread.
InitializeCriticalSection(&g_csCritical);
g_hStopFlag = CreateEvent(NULL, FALSE, FALSE, NULL);
ResetEvent(g_hStopFlag);
// Launch the worker thread.
g_hThread=(HANDLE) _beginthreadex(NULL, 4096,(unsigned int (__stdcall *) (void *)) do_getcalls,
NULL, 0,(unsigned int *) &g_dwThreadID);
// Reset and display error message if thread launch failed.
if (g_hThread == (HANDLE) 0)
{
CloseHandle(g_hVXD); // Release VXD
CloseHandle(g_hStopFlag); // Release event object.
AfxMessageBox(IDP_THREAD_FAIL, MB_ICONSTOP); // Show error message
}
return (g_bIsLogging = (g_hThread != (HANDLE) 0)); // Return logging status to caller.
}
// Signals VxD to stop logging, terminates logging thread, and releases VxD.
void CMainFrame::Stop_Logging(void)
{
// First, tell the VXD to stop recording events.
g_ucUpdate.trap_rec_num = g_dwCondition1;
g_ucUpdate.trap_dat_ptr = (DWORD) &g_tcCond1;
g_ucUpdate.trap_dat_len = sizeof(struct trap_criteria);
g_tcCond1.tc_misc = (APP_EXITING | DISABLE_LOGGING); // Tells VXD to release this record.
DeviceIoControl(g_hVXD, VXD_UPDATE, &g_ucUpdate,
(sizeof(struct upcall)), NULL, 0, NULL, NULL );
if (!g_bLogOpensOnly) // 2nd condition record is not used if logging opens only.
{
g_ucUpdate.trap_rec_num = g_dwCondition2;
g_ucUpdate.trap_dat_ptr = (DWORD) &g_tcCond2;
g_ucUpdate.trap_dat_len = sizeof(struct trap_criteria);
g_tcCond2.tc_misc = (APP_EXITING | DISABLE_LOGGING);
DeviceIoControl(g_hVXD, VXD_UPDATE, &g_ucUpdate,
(sizeof(struct upcall)), NULL, 0, NULL, NULL );
}
CloseHandle(g_hVXD); // Release VXD
SetEvent(g_hStopFlag); // Tell logging thread to stop
CloseHandle(g_hThread); // Clean up associated handles and structure.
CloseHandle(g_hStopFlag);
DeleteCriticalSection(&g_csCritical);
g_bIsLogging = FALSE; // Set logging status.
}
// Adds or deletes our task bar icon.
// Input: func = NIM_ADD or NIM_DELETE.
// Returns: TRUE = success
// FALSE = failure.
BOOL CMainFrame::Do_Taskbar_Icon(UINT func)
{
NOTIFYICONDATA tnid;
BOOL result;
// Initialize common members of TNID structure.
tnid.cbSize = sizeof(tnid);
tnid.hWnd = m_hWnd;
tnid.uID = IDR_MAINFRAME;
tnid.uFlags = 0;
// Set remaining members based on task to be performed.
switch (func)
{
case NIM_ADD: // Add new icon.
tnid.uFlags = NIF_MESSAGE | NIF_ICON | NIF_TIP; // Signal all members valid.
tnid.uCallbackMessage = WM_MY_TASKBAR_NOTIFY; // Set callback message identifier.
// Note: Use LoadImage to make sure we get the small (16 x 16) icon.
tnid.hIcon = (HICON) LoadImage( AfxGetApp()->m_hInstance,
MAKEINTRESOURCE(IDR_MAINFRAME),
IMAGE_ICON,
16,
16,
LR_DEFAULTCOLOR);
break;
case NIM_DELETE: // Remove existing icon.
tnid.hIcon = NULL; // Don't need icon handle for removal.
}
// Set tooltip text if needed.
if (func == NIM_ADD)
lstrcpyn(tnid.szTip, szTip_Text, sizeof(tnid.szTip));
// Call API, return success or failure to caller.
result = Shell_NotifyIcon(func, &tnid);
// Discard the icon if it was loaded
// (Shell_NotifyIcon makes its own copy of the image, so we don't have to waste memory for it).
if (tnid.hIcon)
DestroyIcon(tnid.hIcon);
return result;
}
/////////////////////////////////////////////////////////////////////////////
// Helpers for saving/restoring window state
// Note that these were lifted verbatim from MFC samples.
BOOL CMainFrame::ReadWindowPlacement(LPWINDOWPLACEMENT pwp)
{
CString strBuffer = AfxGetApp()->GetProfileString(g_szSettingKey, "WindowPos");
if (strBuffer.IsEmpty())
return FALSE;
WINDOWPLACEMENT wp;
int nRead = _stscanf(strBuffer, g_szFormat,
&wp.flags, &wp.showCmd,
&wp.ptMinPosition.x, &wp.ptMinPosition.y,
&wp.ptMaxPosition.x, &wp.ptMaxPosition.y,
&wp.rcNormalPosition.left, &wp.rcNormalPosition.top,
&wp.rcNormalPosition.right, &wp.rcNormalPosition.bottom);
if (nRead != 10)
return FALSE;
wp.length = sizeof wp;
*pwp = wp;
return TRUE;
}
void CMainFrame::WriteWindowPlacement(LPWINDOWPLACEMENT pwp)
// write a window placement to settings section of app's ini file
{
TCHAR szBuffer[sizeof("-32767")*8 + sizeof("65535")*2];
wsprintf(szBuffer, g_szFormat,
pwp->flags, pwp->showCmd,
pwp->ptMinPosition.x, pwp->ptMinPosition.y,
pwp->ptMaxPosition.x, pwp->ptMaxPosition.y,
pwp->rcNormalPosition.left, pwp->rcNormalPosition.top,
pwp->rcNormalPosition.right, pwp->rcNormalPosition.bottom);
AfxGetApp()->WriteProfileString(g_szSettingKey, "WindowPos", szBuffer);
}
// Helper function for setting initial toolbar position.
void CMainFrame::DockControlBarLeftOf(CToolBar* Bar, CToolBar* LeftOf)
{
CRect rect;
DWORD dw;
UINT n;
// get MFC to adjust the dimensions of all docked ToolBars
// so that GetWindowRect will be accurate
RecalcLayout();
LeftOf->GetWindowRect(&rect);
rect.OffsetRect(1, 0);
dw=LeftOf->GetBarStyle();
n = 0;
n = (dw & CBRS_ALIGN_TOP) ? AFX_IDW_DOCKBAR_TOP : n;
n = (dw & CBRS_ALIGN_BOTTOM && n==0) ? AFX_IDW_DOCKBAR_BOTTOM : n;
n = (dw & CBRS_ALIGN_LEFT && n==0) ? AFX_IDW_DOCKBAR_LEFT : n;
n = (dw & CBRS_ALIGN_RIGHT && n==0) ? AFX_IDW_DOCKBAR_RIGHT : n;
// When we take the default parameters on rect, DockControlBar will dock
// each Toolbar on a separate line. By calculating a rectangle, we in effect
// are simulating a Toolbar being dragged to that location and docked.
DockControlBar(Bar, n, &rect);
}